package com.sc.nft.controller;

import com.sc.nft.annotation.UserLogin;
import com.sc.nft.controller.request.IdPageRequest;
import com.sc.nft.controller.request.ecologypool.EcologyPoolRedPackPageRequest;
import com.sc.nft.entity.vo.ecologypool.*;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.EcologyPoolRedPackService;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;


@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/redPack")
@Api(tags = "红包活动")
public class EcologyPoolRedPackController {

    private final EcologyPoolRedPackService ecologyPoolRedPackService;
    private final Redisson redisson;


    @ApiOperation(value = "参与记录", notes = "参与记录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/redPackParticipatePage", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<WebEcologyPoolParticipatePageVO> redPackParticipatePage(@RequestBody EcologyPoolRedPackPageRequest request) {
        return PageResult.success(ecologyPoolRedPackService.redPackParticipatePage(UserPool.getUser().getId(), request.getDaoId(), request.getPageNo(), request.getPageSize()));
    }


    @ApiOperation(value = "红包活动列表", notes = "红包活动列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/redPackPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public PageResult<WebEcologyPoolRedPackPageVO> redPackPage(@RequestBody EcologyPoolRedPackPageRequest request) {
        return PageResult.success(ecologyPoolRedPackService.redPackPage(request.getDaoId(), request.getPageNo(), request.getPageSize()));
    }

    @ApiOperation(value = "获取红包状态", notes = "获取红包状态", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/redPackStatus", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<WebEcologyPoolRedPackStatusVO> redPackStatus(@RequestBody @Valid IdPageRequest request) {
        return Result.success(ecologyPoolRedPackService.redPackStatus(request.getId()));
    }

    @ApiOperation(value = "红包详情", notes = "红包详情", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/redPackDetail", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<WebEcologyPoolRedPackDetailVO> redPackDetail(@RequestBody @Valid IdPageRequest request) {
        return Result.success(ecologyPoolRedPackService.redPackDetail(UserPool.getUser().getId(), request.getId()));
    }

    @ApiOperation(value = "打开红包", notes = "打开红包", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/openRedPack", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result<WebEcologyPoolRedPackOpenVO> openRedPack(@RequestBody @Valid IdPageRequest request) {
        Long userId = UserPool.getUserId();
        RLock lock = redisson.getLock(String.format(RedisKeyEnum.OPEN_RED_PACK_LOCK.getKey(), userId));
        try {
            boolean res = lock.tryLock();
            if (!res) {
                throw new GlobalRunTimeException("太火爆了,请稍后再试");
            }
            return Result.success(ecologyPoolRedPackService.openRedPack(userId, request.getId()));
        } catch (GlobalRunTimeException e) {
            log.error("打开红包错误", e);
            throw e;
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }


}
